package com.org.core.dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cglib.beans.BeanMap;

import com.org.core.datasource.DbcpMysqlDataSource;
import com.org.core.utils.BeansUtil;
import com.org.core.utils.StringUtil;

public class CommonDao{
	private static Log log = LogFactory.getLog(CommonDao.class);
	/**
	 * 原生sql查询, 根据指定的类型返回对象
	 * @param <T>
	 * @param sql
	 * @param params 没有可填null
	 * @return
	 * @throws SQLException
	 */
	protected <T> List<T> getList(String sql, Map<Integer, Object> params, Class<T> aimClass) {
		
		java.sql.Connection connection = null;
		List<T> list = new ArrayList<T>();
		ResultSet rs = null;
		PreparedStatement ps = null;
		try{
			connection = getConnectionBak();
			ps = connection.prepareStatement(sql);
			if(params != null) {
				setStatmentParams(ps, params);
			}
			rs = ps.executeQuery();
			
			T entity = null;
			Map<String, Object> res = null;
			while (rs.next()) {
				// 一个指针对应一个entity
				entity = BeansUtil.createBeanJdk(aimClass);
				res = rsToMap(rs);
				BeanMap.create(entity).putAll(res);
				list.add(entity);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				releaseAll(rs, ps, connection);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	

	/**
	 * 获取connection，同时关闭自动提交
	 * @return
	 */
	protected java.sql.Connection getConnection(){
		java.sql.Connection conn = DbcpMysqlDataSource.getInstance().getConnection();
		return conn;
	}
	
	/**
	 * 获取备库connection，同时关闭自动提交
	 * @return
	 */
	protected java.sql.Connection getConnectionBak(){
		java.sql.Connection conn = DbcpMysqlDataSource.getInstance().getConnectionBak();
		return conn;
	}
	
	protected void setStatmentParams(PreparedStatement ps, Map<Integer, Object> params) throws SQLException{
		if(params == null || params.size() <= 0) {
			return;
		}
		for (Iterator<Integer> iterator = params.keySet().iterator(); iterator
				.hasNext();) {
			Integer key = iterator.next();
			ps.setObject(key, params.get(key));
		}
	}

	protected static Map<String, Object> rsToMap(ResultSet rs) throws SQLException {
		
		ResultSetMetaData rsmd = rs.getMetaData();
		// 列数
		int columnCounts = rsmd.getColumnCount();
		
		Map<String, Object> map = new HashMap<String, Object>();
		String key = null;
		Object value = null;
		for (int i = 1; i <= columnCounts; i++) {
			key = rsmd.getColumnName(i);
			log.info("rsToMap======>"+key + "类型:" + rsmd.getColumnTypeName(i));
			// 转驼峰
			key = StringUtil.toEntityName(key, true);
			// 首字母大写
			//key = String.valueOf(key.charAt(0)).toUpperCase() + key.substring(1);
			value = rs.getObject(i);
			map.put(key, value);
		}
		return map;
	}

	protected <T> T getSingle(String sql, Map<Integer, Object> params, Class<T> clazz) {
		java.sql.Connection connection = null;
		ResultSet rs = null;
		PreparedStatement ps = null;
		T entity = null;
		try{
			connection = getConnectionBak();
			ps = connection.prepareStatement(sql);
			setStatmentParams(ps, params);
			rs = ps.executeQuery();
			while(rs.next()){
				entity = BeansUtil.createBeanJdk(clazz);
				Map<String, Object> res = rsToMap(rs);
				BeanMap.create(entity).putAll(res);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				releaseAll(rs, ps, connection);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}			
		return entity;
	}
	
	protected Integer getCount(String sql, Map<Integer, Object> params, String key){
		java.sql.Connection connection = null;
		ResultSet rs = null;
		PreparedStatement ps = null;

		Integer returnInteger = null;
		try{
			connection = getConnectionBak();
			ps = connection.prepareStatement(sql);
			if(params != null){
				setStatmentParams(ps, params);
			}
			rs = ps.executeQuery();
			while(rs.next()){
				returnInteger = rs.getInt(key);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				releaseAll(rs, ps, connection);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return returnInteger;
	}
	
	private void releaseAll(ResultSet rs, PreparedStatement ps,
			java.sql.Connection connection) throws SQLException {
		if(rs != null){
			rs.close();
		}
		if(ps != null){
			ps.close();
		}
		if(connection != null){
			connection.close();
		}
	}
}
